using System;
using System.Globalization;
using System.Text;
using GooglePlayGames.BasicApi;
using GooglePlayGames.BasicApi.SavedGame;
using UnityEngine;

namespace BCW
{
	internal sealed class GooglePushHelper
	{
		private const string SavedGameClientIsNullMessage = "[Rilisoft] SavedGame client is null.";

		private bool _invoked;

		private DataSource _currentDataSource = DataSource.ReadNetworkOnly;

		private string _accumulatedMerge;

		private readonly string _filename;

		private readonly Func<string, string, string> _merger;

		private readonly string _data;

		private readonly Action<bool> _commitComplete;

		private string Filename
		{
			get
			{
				return _filename;
			}
		}

		private static ISavedGameClient SavedGame
		{
			get
			{
				try
				{
					return GpgWrapper.instance.SavedGame;
				}
				catch (NullReferenceException)
				{
					return null;
				}
			}
		}

		internal GooglePushHelper(string filename, Func<string, string, string> merger, string data, Action<bool> CommitComplete)
		{
			if (merger == null)
			{
				throw new ArgumentNullException("merger");
			}
			_filename = filename ?? string.Empty;
			_merger = merger;
			_data = data;
		}

		internal void Run()
		{
			bool flag = GpgWrapper.instance.IsAuthenticated();
			if (!_invoked)
			{
				_invoked = true;
				if (flag)
				{
					RunAuthenticated();
				}
			}
		}

		private void RunAuthenticated()
		{
			if (SavedGame != null)
			{
				SavedGame.OpenWithManualConflictResolution(Filename, _currentDataSource, true, HandleOpenConflict, HandleOpenCompleted);
			}
		}

		private void HandleOpenConflict(IConflictResolver resolver, ISavedGameMetadata original, byte[] originalData, ISavedGameMetadata unmerged, byte[] unmergedData)
		{
			try
			{
				if (originalData == null)
				{
					resolver.ChooseMetadata(unmerged);
					return;
				}
				if (unmergedData == null)
				{
					resolver.ChooseMetadata(original);
					return;
				}
				string text = Encoding.UTF8.GetString(originalData, 0, originalData.Length) ?? string.Empty;
				string text2 = Encoding.UTF8.GetString(unmergedData, 0, unmergedData.Length) ?? string.Empty;
				string text3 = _merger(text, text2);
				if (object.ReferenceEquals(text3, text))
				{
					resolver.ChooseMetadata(original);
					return;
				}
				if (object.ReferenceEquals(text3, text2))
				{
					resolver.ChooseMetadata(unmerged);
					return;
				}
				if (_accumulatedMerge == null)
				{
					_accumulatedMerge = text3;
				}
				else
				{
					_accumulatedMerge = _merger(_accumulatedMerge, text3);
				}
				ISavedGameMetadata savedGameMetadata;
				if (original.LastModifiedTimestamp >= unmerged.LastModifiedTimestamp)
				{
					savedGameMetadata = original;
				}
				else
				{
					savedGameMetadata = unmerged;
				}
				ISavedGameMetadata chosenMetadata = savedGameMetadata;
				resolver.ChooseMetadata(chosenMetadata);
			}
			catch (Exception ex)
			{
				BCWDebug.Log(string.Format("Request failed with `{0}`: {1}", ex.GetType(), ex.Message), "GPG", LogType.Exception);
			}
		}

		private void HandleOpenCompleted(SavedGameRequestStatus requestStatus, ISavedGameMetadata metadata)
		{
			try
			{
				switch (requestStatus)
				{
				case SavedGameRequestStatus.Success:
				{
					string text = ((_accumulatedMerge == null) ? _data : _merger(_accumulatedMerge, _data));
					string text2 = ((_accumulatedMerge == null) ? "none" : "merged");
					BCWDebug.Log(string.Format("conflict: {0}, result: {1}", text2, text ?? string.Empty), "GPG");
					string description = string.Format(CultureInfo.InvariantCulture, "device:'{0}', conflict:'{1}'", SystemInfo.deviceModel, text2);
					SavedGameMetadataUpdate updateForMetadata = default(SavedGameMetadataUpdate.Builder).WithUpdatedDescription(description).Build();
					byte[] bytes = Encoding.UTF8.GetBytes(text ?? string.Empty);
					SavedGame.CommitUpdate(metadata, updateForMetadata, bytes, HandleCommitCompleted);
					break;
				}
				case SavedGameRequestStatus.TimeoutError:
					if (_currentDataSource == DataSource.ReadCacheOrNetwork)
					{
						BCWDebug.Log("Exception: " + requestStatus, "GPG", LogType.Error);
						break;
					}
					_currentDataSource = DataSource.ReadCacheOrNetwork;
					SavedGame.OpenWithManualConflictResolution(Filename, _currentDataSource, true, HandleOpenConflict, HandleOpenCompleted);
					break;
				default:
					BCWDebug.Log("Exception: " + requestStatus, "GPG", LogType.Exception);
					break;
				}
			}
			catch (Exception ex)
			{
				BCWDebug.Log(string.Format("Request failed with `{0}`: {1}", ex.GetType(), ex.Message), "GPG", LogType.Exception);
			}
		}

		private void HandleCommitCompleted(SavedGameRequestStatus requestStatus, ISavedGameMetadata metadata)
		{
			try
			{
				if (_commitComplete != null)
				{
					_commitComplete(requestStatus == SavedGameRequestStatus.Success);
				}
			}
			catch (Exception ex)
			{
				BCWDebug.Log(string.Format("Request failed with `{0}`: {1}", ex.GetType(), ex.Message), "GPG", LogType.Exception);
			}
		}
	}
}
